package br.ifrn.diacin.ctrlAula.integracao.model;

import java.util.ArrayList;
import java.util.Date;
import java.util.GregorianCalendar;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
import javax.persistence.Transient;

@Entity
@Table(name="tb_reserva")
public class Reserva {
	
	@Id @GeneratedValue
	@Column(name="pk_id_reserva")
	private int id;
	@Column(name="st_confirmado")
	private Boolean reservaConfirmada;
	@Column(name="st_semesteral")
	private Boolean reservaSemenstral;
	@Column(name="dz_reserva")
	@Temporal(TemporalType.DATE)
	private Date dataReserva;
	@Column(name="dz_confirmacao")
	private Date dataConfirmacao;
	
	@Enumerated(EnumType.STRING)
	private Horarios horarioReserva;
	
	@Transient
	private boolean reservado;
	

	@OneToMany(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinColumn(name="fk_horario")
	private List<Horario> horarios;
	
	@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinColumn(name="fk_professor")
	private Usuario professor;
	
	@ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinColumn(name="fk_ambiente")
	private Ambiente ambiente;
	
	
	@ManyToMany(cascade={CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH})
	@JoinTable(name="tb_reserva_suprimentos",
			joinColumns={@JoinColumn(name=
					"fk_reserva")}, inverseJoinColumns=
						{@JoinColumn(name="fk_suprimentos_utilizados")})
	private List<Suprimento> suprimentosUtilizados;

	public Reserva() {}
	
	public Reserva(Usuario professor, Boolean reservaSemestral) {
		this.professor = professor;
		this.reservaSemenstral = reservaSemestral;
		horarios = new ArrayList<Horario>();
		suprimentosUtilizados = new ArrayList<Suprimento>();
		this.reservaConfirmada = false;
	}
	
	
	
	/**
	 * @return the id
	 */
	public int getId() {
		return id;
	}

	/**
	 * @param id the id to set
	 */
	public void setId(int id) {
		this.id = id;
	}

	/**
	 * @return the horarioInicial
	 */
	public List<Horario> getHorarios() {
		return horarios;
	}

	/**
	 * @param horarioInicial the horarioInicial to set
	 */
	public void setHorarios(List<Horario> horarios) {
		this.horarios = horarios;
	}

	/**
	 * @return the horarioFinal
	 */
	public void addHorario(Horario horario) {
		horarios.add(horario);
	}


	/**
	 * @return the reservaConfirmada
	 */
	public Boolean getReservaConfirmada() {
		return reservaConfirmada;
	}

	/**
	 * @param reservaConfirmada the reservaConfirmada to set
	 */
	public void setReservaConfirmada(Boolean reservaConfirmada) {
		this.reservaConfirmada = reservaConfirmada;
	}

	/**
	 * @return the reservaSemenstral
	 */
	public Boolean getReservaSemenstral() {
		return reservaSemenstral;
	}

	/**
	 * @param reservaSemenstral the reservaSemenstral to set
	 */
	public void setReservaSemenstral(Boolean reservaSemenstral) {
		this.reservaSemenstral = reservaSemenstral;
	}

	/**
	 * @return the dataReserva
	 */
	public Date getDataReserva() {
		return dataReserva;
	}

	/**
	 * @param dataReserva the dataReserva to set
	 */
	public void setDataReserva(Date dataReserva) {
		this.dataReserva = dataReserva;
	}

	/**
	 * @return the dataConfirmacao
	 */
	public Date getDataConfirmacao() {
		return dataConfirmacao;
	}

	/**
	 * @param dataConfirmacao the dataConfirmacao to set
	 */
	public void setDataConfirmacao(Date dataConfirmacao) {
		this.dataConfirmacao = dataConfirmacao;
	}

	/**
	 * @return the professorResponsavel
	 */
	public Usuario getProfessor() {
		return professor;
	}

	/**
	 * @param professorResponsavel the professorResponsavel to set
	 */
	public void setProfessor(Usuario professor) {
		this.professor = professor;
	}

	/**
	 * @return the suprimentosUtilizados
	 */
	public List<Suprimento> getSuprimentosUtilizados() {
		return suprimentosUtilizados;
	}

	/**
	 * @param suprimentosUtilizados the suprimentosUtilizados to set
	 */
	public void setSuprimentosUtilizados(List<Suprimento> suprimentosUtilizados) {
		this.suprimentosUtilizados = suprimentosUtilizados;
	}

	public void setAmbiente(Ambiente ambiente) {
		this.ambiente = ambiente;
	}

	public Ambiente getAmbiente() {
		return ambiente;
	}

	public Horarios getHorarioReserva() {
		return horarioReserva;
	}

	public void setHorarioReserva(Horarios horarioReserva) {
		this.horarioReserva = horarioReserva;
	}

	public boolean isReservado() {
		return reservado;
	}

	public void setReservado(boolean reservado) {
		this.reservado = reservado;
	}

	@Override
	public int hashCode() {
		final int prime = 31;
		int result = 1;
		result = prime * result
				+ ((ambiente == null) ? 0 : ambiente.hashCode());
		result = prime * result
				+ ((dataConfirmacao == null) ? 0 : dataConfirmacao.hashCode());
		result = prime * result
				+ ((dataReserva == null) ? 0 : dataReserva.hashCode());
		result = prime * result
				+ ((horarios == null) ? 0 : horarios.hashCode());
		result = prime * result + id;
		result = prime * result
				+ ((professor == null) ? 0 : professor.hashCode());
		result = prime
				* result
				+ ((reservaConfirmada == null) ? 0 : reservaConfirmada
						.hashCode());
		result = prime
				* result
				+ ((reservaSemenstral == null) ? 0 : reservaSemenstral
						.hashCode());
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (obj == null)
			return false;
		if (getClass() != obj.getClass())
			return false;
		Reserva other = (Reserva) obj;
		if (ambiente == null) {
			if (other.ambiente != null)
				return false;
		} else if (!ambiente.equals(other.ambiente))
			return false;
		if (dataConfirmacao == null) {
			if (other.dataConfirmacao != null)
				return false;
		} else if (!dataConfirmacao.equals(other.dataConfirmacao))
			return false;
		if (dataReserva == null) {
			if (other.dataReserva != null)
				return false;
		} else if (!dataReserva.equals(other.dataReserva))
			return false;
		if (horarios != other.horarios)
			return false;
		if (id != other.id)
			return false;
		if (professor == null) {
			if (other.professor != null)
				return false;
		} else if (!professor.equals(other.professor))
			return false;
		if (reservaConfirmada == null) {
			if (other.reservaConfirmada != null)
				return false;
		} else if (!reservaConfirmada.equals(other.reservaConfirmada))
			return false;
		if (reservaSemenstral == null) {
			if (other.reservaSemenstral != null)
				return false;
		} else if (!reservaSemenstral.equals(other.reservaSemenstral))
			return false;
		return true;
	}
	
}
